package com.ht.filter;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson.JSON;
import com.ht.config.security.MyUserDetailsService;
import com.ht.config.security.handler.LocalAuthenticationFailureHandler;
import com.ht.constant.RedisConstants;
import com.ht.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;


/**
 * @ProjectName: ht
 * @ClassName: JwtAuthenticationTokenFilter
 * @Author: hejialun
 * @Description: JWT验证过滤器
 * @Date: 2021/6/20 16:51
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private MyUserDetailsService myUserDetailsService;
    //token过期时间
    @Value("${jwt.expireTime}")
    public long EXPIRE_TIME;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //token权限设置
        String token  = UserUtil.getTokenByRequest(request);
        if(StrUtil.isNotEmpty(token)){
            //去redis里面获取token信息
            Map<String, Object> map = (Map<String, Object>) redisUtil.get(RedisConstants.USER_INFOS_PREFIX + token);
            if(ObjectUtil.isNotEmpty(map)){
                //判断token是否过期
                String username = map.get("username").toString();
                try {
                    //重新查询用户
                    UserDetails userDetails = myUserDetailsService.loadUserByUsername(username);
                    //设置权限
                    if (userDetails != null) {
                        //刷新token过期时间
                        redisUtil.expire(RedisConstants.USER_INFOS_PREFIX + token,EXPIRE_TIME);
                        UsernamePasswordAuthenticationToken authentication =
                                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                } catch (Exception e) {
                    response.setCharacterEncoding("utf-8");
                    response.setContentType("application/json;charset=utf-8");
                    response.getWriter().print(JSON.toJSONString(JsonResult.error(e.getMessage())));
                    return;
                }
            }else{
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().print(JSON.toJSONString(JsonResult.error(ResultEnum.LOGIN_IS_OVERDUE.getMessage(),ResultEnum.LOGIN_IS_OVERDUE.getCode())));
                return;
            }
        }

        filterChain.doFilter(request, response);
    }



}